// Copyright (c) 2010, Anthony Cassidy
// All rights reserved.
// 
// Redistribution and use in source and binary forms, with or without modification, are 
// permitted provided that the following conditions are met:
// 
//     * Redistributions of source code must retain the above copyright notice, this list 
//         of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice, this 
//         list of conditions and the following disclaimer in the documentation and/or 
//         other materials provided with the distribution.
//     * Neither the name of the AntsAdventureGameCreator nor the names of its contributors 
//         may be used to endorse or promote products derived from this software without 
//         specific prior written permission.
// 
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
// THE POSSIBILITY OF SUCH DAMAGE.
#include "XStdafx.h"
#include "XCommandLine.h"
#include "XThreadForOnEnterRoomAndOnCommandLine.h"

#include "XDiagnostics.h"



XCommandLine::XCommandLine()
: m_defaultVerb("Walk to AAA","1")
, m_lockedInVerb("","")
, m_lockedInObject1("","")
, m_lockedInObject2("","")
, m_rolledOver("","")
, m_typeOfRollover("")
, m_isMouseable(true)
, m_isVisible(true)
{

}

XCommandLine::~XCommandLine()
{
    XDiagnostics::Delete("XCommandLine");
}

bool XCommandLine::IsVisible() const
{ 
    return m_isVisible;
}

QImage XCommandLine::GetImage()
{
    return m_image;
}

bool IsAVerb(XStringNumberCombo snc)
{
    return snc.DisplayName().contains("AAA") || snc.DisplayName().contains("BBB");
}

bool IsAnObject(XStringNumberCombo snc)
{
    return !IsAVerb(snc);
}

void XCommandLine::UpdateImage()
{
    // initialize image and painter
    QImage image(m_rect.width(), m_rect.width(), QImage::Format_ARGB32_Premultiplied);

    // set alpha channel of image
    QImage black(image.width(),image.height(), QImage::Format_Mono);
    black.fill(0);
    image.setAlphaChannel(black);

    // draw black bg
    QPainter painter;
    bool isOk = painter.begin(&image);
    if(isOk)
    {
        painter.fillRect(m_rect, m_isMouseable? QBrush(Qt::black):QBrush(Qt::darkMagenta));


        // draw text
        painter.setFont(m_font);
        painter.setPen(Qt::cyan);
        XSentence sentence = GetSentence();
        sentence.SetBBB(XStringNumberCombo());
        sentence.SetAAA(XStringNumberCombo());
        painter.drawText(m_rect, Qt::AlignLeft|Qt::TextSingleLine, sentence.DisplayName());
        bool isOk2 = painter.end();
        (isOk2 = isOk2);
        ASSERT(isOk2 && "paint failed in XCommandline");
    }
    m_image = image;
}

void XCommandLine::DrawCommandLineIfVisible(QPainter& painter, bool forceRolloverOff)
{
    if(m_isVisible)
    {
        painter.drawImage(0,0,m_image);
    }
}

XSentence XCommandLine::GetSentence()
{
    XSentence text;

    // choose XVerb: one or two object form	
    if(!IsAVerb(m_rolledOver))
    {
        if(m_lockedInVerb.Length())
        {
            // set verb
            text.SetVerb( m_lockedInVerb );

            // if contains 2 forms, then refine the appearance
            int i = m_lockedInVerb.LastIndexOf("|");
            if(i!=-1)
            {
                //bool isFirstObjectLockedIn = m_lockedInObject1.length();
                //text.SetVerb(isFirstObjectLockedIn? m_lockedInVerb.mid(i+1) : m_lockedInVerb.left(i));
                // if its a 2-form verb, then show extended form no matter what
                text.SetVerb( m_lockedInVerb.Mid(i+1));
            }

            if(m_lockedInVerb.Contains("BBB"))
            {
                if(m_lockedInObject2.DisplayName().isEmpty())
                {
                    if(m_lockedInObject1.DisplayName().isEmpty())
                    {
                        m_typeOfRollover = "A";
                        text.SetAAA(m_rolledOver);
                        //text.SetBBB("");
                    }else
                    {
                        m_typeOfRollover = "B";
                        text.SetAAA(m_lockedInObject1);
                        text.SetBBB(m_rolledOver );
                    }
                }
                else
                {
                    text.SetAAA(m_lockedInObject1);
                    text.SetBBB(m_lockedInObject2);
                }
            }
            else
            {
                if(m_lockedInObject1.Length())
                {
                    text.SetAAA(m_lockedInObject1);
                }
                else
                {
                    m_typeOfRollover = "A";
                    text.SetAAA(m_rolledOver);
                }
            }
        }else if(m_lockedInObject1.Length())
        {
            m_typeOfRollover = "";
            text.SetVerb( m_defaultVerb );
            text.SetAAA( m_lockedInObject1);
        }
        else
        {
            m_typeOfRollover = "A";
            text.SetVerb( m_defaultVerb );
            text.SetAAA( m_rolledOver);
        }
    }else
    {
        m_typeOfRollover = "V";

        // set the verb
        text.SetVerb( m_rolledOver );

        // if contains 2 forms, then refine the appearance
        int i = m_rolledOver.LastIndexOf("|");
        if(i!=-1)
        {
            bool isFirstObjectLockedIn = m_lockedInObject1.Length();
            text.SetVerb( isFirstObjectLockedIn? m_rolledOver.Mid(i+1) : m_rolledOver.Left(i) );
        }

        // if obj1, set obj1
        if (m_lockedInObject1.Length())
        {
            text.SetAAA( m_lockedInObject1);
        }
        // if obj2, set obj2
        if (m_lockedInObject2.Length())
        {
            text.SetBBB( m_lockedInObject2);
        }
    }

    //text += "XVerb "+ m_lockedInVerb + "obj1 " + m_lockedInObject1 + "obj2 " + m_lockedInObject2;

    return text;
}

void XCommandLine::SetRollover(QString displayName, QString keyword)
{ 
    m_rolledOver  = XStringNumberCombo(displayName,keyword); 
    UpdateImage();
}

void XCommandLine::OnRightClick()
{
    Clear();
}

void XCommandLine::Clear()
{
    m_lockedInObject1 = XStringNumberCombo("");
    m_lockedInObject2 = XStringNumberCombo("");
    m_lockedInVerb = XStringNumberCombo("");
    m_rolledOver = XStringNumberCombo("");
    m_typeOfRollover = "";
    UpdateImage();
}

void XCommandLine::DoNextBestThingToExecute()
{
    if(m_typeOfRollover == "A")
    {
        m_lockedInObject1 = m_rolledOver;
        m_rolledOver = XStringNumberCombo("");
        m_typeOfRollover = "";
    }
    else if(m_typeOfRollover == "B")
    {
        m_lockedInObject2 = m_rolledOver;
        m_rolledOver = XStringNumberCombo("");
        m_typeOfRollover = "";
    }
    else if(m_typeOfRollover == "V")
    {
        m_lockedInVerb = m_rolledOver;
        m_rolledOver = XStringNumberCombo("");
        m_typeOfRollover = "";
    }
    UpdateImage();
}

void XCommandLine::Execute(XThreadForOnEnterRoomAndOnCommandLine& thread, int x, int y)
{
    // if its incomplete, the clear everything..
    if(!IsOkToExecute())
    {
        Clear();
        return;
    }

    thread.CallOnCommandLineExecute(GetSentence().VerbAsCode(), GetSentence().A(), GetSentence().B(), x, y );
}

bool XCommandLine::IsOkToExecute()
{
    //DoNextBestThingToExecute();

    QString command = GetSentence().DisplayName();
    return !command.contains("AAA") && !command.contains("BBB");
}

void XCommandLine::SetMouseable(bool mouseable)
{
    m_isMouseable = mouseable;
    UpdateImage();
}

void XCommandLine::SetVisible(bool isVisible)
{
    m_isVisible = isVisible;
}

int XCommandLine::GetVerbAsVerbEnumeration()
{
    int currentVerb = GetSentence().VerbAsVerbEnumeration();
    return currentVerb;
}
